/**
 * 编写一个算法来判断一个数 n 是不是快乐数。
 *
 * 「快乐数」定义为：
 *
 * 对于一个正整数，每一次将该数替换为它每个位置上的数字的平方和。
 * 然后重复这个过程直到这个数变为 1，也可能是 无限循环 但始终变不到 1。
 * 如果这个过程 结果为1，那么这个数就是快乐数。
 * 如果 n 是 快乐数 就返回 true ；不是，则返回 false 。
 *分析：第一种：最后得到1
 *     第二种：进入循环
 *     第三种：无穷大
 *     但是第三种是不可能的
 *  第三个情况比较难以检测和处理。我们怎么知道它会继续变大，而不是最终得到 11 呢？我们可以仔细想一想，每一位数的最大数字的下一位数是多少。
 *
 * Digits	Largest	Next
 * 1	       9	81
 * 2	      99	162
 * 3	     999	243
 * 4	    9999	324
 * 13	 9999999999999	1053
 * 对于 3 位数的数字，它不可能大于 243。这意味着它要么被困在 243 以下的循环内，要么跌到 1。4 位或 4 位以上的数字在每一步都会丢失一位，直到降到 3 位为止。所以我们知道，最坏的情况下，算法可能会在 243 以下的所有数字上循环，然后回到它已经到过的一个循环或者回到 1。但它不会无限期地进行下去，所以我们排除第三种选择。
 *
 * 即使在代码中你不需要处理第三种情况，你仍然需要理解为什么它永远不会发生，这样你就可以证明为什么你不处理它。
 *通过反复调用 getNext(n) 得到的链是一个隐式的链表。隐式意味着我们没有实际的链表节点和指针，但数据仍然形成链表结构。起始数字是链表的头 “节点”，链中的所有其他数字都是节点。next 指针是通过调用 getNext(n) 函数获得。
 *
 * 意识到我们实际有个链表，那么这个问题就可以转换为检测一个链表是否有环。因此我们在这里可以使用弗洛伊德循环查找算法。这个算法是两个奔跑选手，一个跑的快，一个跑得慢。在龟兔赛跑的寓言中，跑的慢的称为 “乌龟”，跑得快的称为 “兔子”。
 *
 * 不管乌龟和兔子在循环中从哪里开始，它们最终都会相遇。这是因为兔子每走一步就向乌龟靠近一个节点（在它们的移动方向上）。
 *
 * https://leetcode.cn/problems/happy-number/solution/kuai-le-shu-by-leetcode-solution/
 */
class IsHappy {
    public int getNext(int n){
        int sum=0;
        while(n!=0){
            int tmp=n%10;
            sum+=(tmp*tmp);
            n/=10;
        }
        return sum;
    }
    public boolean isHappy(int n) {
       int slow=n;
       int fast=getNext(n);
       while(fast!=1&&slow!=fast){
           slow=getNext(slow);
           fast=getNext(getNext(fast));
       }
       return fast==1;
    }
}